﻿using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Primitives;
using NXDO.WebAPI.Controllers;
using NXDO.WebAPI.Jwt;
using NXDO.WebAPI.Web;
using System;
using System.Linq;
using System.Net;
using System.Text;
using TDM.DbData.DataEntity;
using TDM.WebBiz.Security;

namespace TDM.WebSvr.Controllers
{
    /// <summary>
    /// 登录控制器
    /// </summary>
    public class LoginController : ApiEntityLoginController<DaUser>
    {

        protected override string GetFieldNameForSafeUser()
        {
            //后续加字段用于存放8所用户信息的： 字段名
            return "UserName";
        }

        protected override bool IsSafeDomainName(NetworkCredential credential, string configSafeDomain)
        {
            //credential.Domain 与配置是否相同
            //base.login 中被调用进行判断
            //是安全域时，不需要密码即可登录
            return base.IsSafeDomainName(credential, configSafeDomain);
        }

        /// <summary>
        /// 重定向安全域请求
        /// </summary>
        [HttpGet, AllowAnonymous]
        public void Goto8Safe()
        {
            StringValues val;
            var checkExists = HttpContext.Request.Headers.TryGetValue("dnname", out val);
            if (!checkExists) return;

            //imro8 - authentication@safeDomain
            //http://localhost:5050/login?imro8=xxxx;
            //var rs= this.GetConfigSafeReferer(); //用于判断当前请求来源是否在配置中

            var safeQueryKey = this.GetConfigSafeDomain();
            var safeLoginUrl = this.GetSafeLoginUrl();

            var v = string.Join("&", val.ToArray());
            var url = $"{safeLoginUrl}?{safeQueryKey}={WebUtility.UrlEncode(v)}";
            //HttpContext.Response.Redirect(url);
            //return url;
            var resp = HttpContext.Response;
            resp.ContentType = "text/html; charset=UTF-8";

            StringBuilder htmlStringBuilder = new StringBuilder();
            htmlStringBuilder.Append("<html>");
            htmlStringBuilder.Append("<head>");
            htmlStringBuilder.Append("<script>");
            htmlStringBuilder.Append("function gotoUrl(url){document.location.href=url;}");
            htmlStringBuilder.Append("</script>");
            htmlStringBuilder.Append("</head>");
            htmlStringBuilder.Append("<body>");
            htmlStringBuilder.Append("<script> gotoUrl('");
            htmlStringBuilder.Append(url);
            htmlStringBuilder.Append("');</script>");
            htmlStringBuilder.Append("</body>");
            htmlStringBuilder.Append("</html>");
            var result = htmlStringBuilder.ToString();
            var data = Encoding.UTF8.GetBytes(result);
            resp.StatusCode = 200;
            resp.Body.WriteAsync(data, 0, data.Length).Wait();
        }


        /// <summary>
        /// 执行登录
        /// </summary>
        /// <param name="credential"></param>
        /// <returns></returns>
        public override object Login([FromBody] NetworkCredential credential)
        {
            try
            {
                var isSafeDomain = false;
                var safeDomain = this.GetConfigSafeDomain();
                if (string.Compare(credential.Domain, safeDomain, true) == 0)
                {
                    //CN=WRJ,T=jay
                    var name = credential.UserName;
                    if (string.IsNullOrEmpty(name)) return StatusCode(500);
                    name = WebUtility.UrlDecode(name);
                    var ary = name.Split("=");
                    credential.UserName = ary[ary.Length - 1];
                    credential.Password = "";
                    isSafeDomain = true;
                }
                //else if (credential.Domain == "vue" && (credential.UserName != "test" && credential.UserName != "jay"))
                //{
                //    throw new Exception("非网关入口进入，禁止登录");//主系统通过网址输入用户名登录，正式部署系统内关闭
                //}
                else
                {
                    //Domain的值为client，便携式系统登录，需要验证密码
                }

                var rs = base.Login(credential);
                var user = DaUserHelper.GetUser(credential.UserName);
                if (user != null)
                {
                    if (isSafeDomain)
                    {
                        var role = DaRoleHelper.GetRole(user.RoleId);
                        if (role != null && role.AdminFlag > 0)
                        {
                            throw new Exception("管理员用户,禁止登录");
                        }
                    }
                    this.AppendCookie(user.RealName, user.SecurityLevel.HasValue ? user.SecurityLevel.Value.ToString() : "");
                }
                return rs;
            }
            catch (Exception e)
            {
                //System.Diagnostics.Debug.Write(e);
                throw new Exception(e.Message);
            }

            //return Ok();
        }

        private void AppendCookie(string realName, string securityLvl)
        {
            var cookNameRN = "X-NXDO-RealName";// ApiLoginController.GetCookieNameForRealName();
            var cookNameMJ = "X-NXDO-MJ";
            var isCros = this.Request.IsCros();
            if (isCros)
            {
                if (this.Response.Headers.AccessControlExposeHeaders.Any())
                {
                    //已在登录成功处设置了，则清除
                    //本方法为cros需要追加头部信息(原cookie设置输出，则cros时由头部进行输出)
                    this.Response.Headers.AccessControlExposeHeaders = new Microsoft.Extensions.Primitives.StringValues();
                }

                var keyAuthorization = JTokenBuilder.JTokenHeaderKeyAuthorization;
                this.Response.Headers.Add("Access-Control-Expose-Headers", $"{keyAuthorization}, {cookNameRN},{cookNameMJ},X-NXDO-Token, Set-Cookie, Cookie, Origin, X-Requested-With, Content-Type, Accept, Token");
                //this.Response.Headers.Add(cookNameRN, WebUtility.UrlEncode((memberPrincipal.Identity as MemberIdentity).RealName));
                //this.Response.Headers.Add("Access-Control-Expose-HeadersMJ", $"{keyAuthorization}, {cookNameMJ},X-NXDO-Token, Set-Cookie, Cookie, Origin, X-Requested-With, Content-Type, Accept, Token");
                this.Response.Headers.Add(cookNameRN, WebUtility.UrlEncode(realName));
                this.Response.Headers.Add(cookNameMJ, WebUtility.UrlEncode(securityLvl));
            }
            else
            {
                //var ii = memberPrincipal.Identity as MemberIdentity;
                //var rrName = ii.RealName ?? "tt";
                var rrName = realName;
                var tExpires = DateTime.Now.AddMinutes(10d);

                //js可读的信息
                var optJsCanRead = new CookieOptions { HttpOnly = false, Expires = tExpires, Secure = true };
                //var optJsCanRead = new CookieOptions { HttpOnly = true, Expires = tExpires };
                //HttpContext.Response.Cookies.Append("X-NXDO-UserName", (memberPrincipal.Identity as MemberIdentity).Name, optJsCanRead);
                var keyAuthorization = JTokenBuilder.JTokenHeaderKeyAuthorization;
                HttpContext.Response.Headers.Add("Access-Control-Expose-Headers", $"{keyAuthorization}, {cookNameRN},{cookNameMJ},X-NXDO-Token, Set-Cookie, Cookie, Origin, X-Requested-With, Content-Type, Accept, Token");
                HttpContext.Response.Headers.Add(cookNameRN, WebUtility.UrlEncode(realName));
                HttpContext.Response.Headers.Add(cookNameMJ, WebUtility.UrlEncode(securityLvl));
                HttpContext.Response.Cookies.Append(cookNameRN, rrName, optJsCanRead);
                HttpContext.Response.Cookies.Append(cookNameMJ, securityLvl.ToString(), optJsCanRead);
                //不在需要，js是使用vue路由转向，不是window.location的转向，故此不需要cookie，如果需要客户端可以设置cookie
                ////js不可读的信息
                //var bearer = HttpContext.Response.Headers.Authorization;
                //var optJsUnRead = new CookieOptions { HttpOnly = true, Expires = tExpires };
                //HttpContext.Response.Cookies.Append(JTokenBuilder.JTokenAuthorizationCookieName, bearer.FirstOrDefault() ?? "", optJsUnRead);
            }
        }

    }
}
